﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace airwolf.HTTP
{
    public class Server
    {
        private List<TcpClient> _clientQueue = new List<TcpClient>();
        private Dictionary<string, IHTTPHandler> _table = new Dictionary<string, IHTTPHandler>();
        private bool _listen = false;
        string _ip;
        //int _port = 20202;

        public Server()
        {
            _ip = IP.LocalAddress;
        }

        public void Start()
        {
            TcpListener listener = new TcpListener(IPAddress.Parse(_ip), Port);
            _listen = true;

            try
            {
                listener.Start();

                while (_listen)
                {
                    Console.WriteLine("HTTP server listening on {0}:{1}", _ip, Port);
                    TcpClient client = listener.AcceptTcpClient();

                    lock (_clientQueue)
                    {
                        _clientQueue.Add(client);
                    }

                    System.Threading.ThreadPool.QueueUserWorkItem(WorkerStart, client);
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                listener.Stop();
            }
        }

        public void Stop()
        {
            //Thread stopListening = new Thread(delegate() { _listen = false; });
            //stopListening.Start();
        }

        private void WorkerStart(object state)
        {
            //lock (_clientQueue)
            //{
            //    if (_clientQueue.Count < 1)
            //        return;
            //
            //    Worker worker = new Worker(_clientQueue[0]);
            //    _clientQueue.RemoveAt(0);
            //}
            TcpClient client = (TcpClient)state;
            Worker worker = new Worker(this, client);
        }

        public void RegisterHandler(string Path, IHTTPHandler Handler)
        {
            _table.Add(Path, Handler);
        }

        internal HTTPResult Route(string URI, string Message)
        {
            if (_table.ContainsKey(URI))
                return new HTTPResult(Headers.OK, _table[URI].Handle(URI, Message));
            else if (_table.ContainsKey("*"))
                return new HTTPResult(Headers.OK, _table["*"].Handle(URI, Message));
            else
                return new HTTPResult(Headers.NotFound, "", ContentTypes.None);
        }

        public static int Port
        {
            get
            {
                return 20202;
            }
        }

        public static string Name
        {
            get
            {
                return "Airwolf";
            }
        }
    }
}
